package com.googlecode.grs.environment;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.StringTokenizer;

/**
 * Factory that generates scenarios containing robot and obstacles associated
 * with scenario--can be loaded from file or generated on the fly
 * 
 * @author anand
 * 
 */
public class SimulationEnvironmentFactory {
	public static double WALL_WIDTH = 10;

	/**
	 * 
	 * @return an example default configuration
	 */
	public static SimulationEnvironment getDefaultConfiguration() {
		SimulationEnvironment env = new SimulationEnvironment();
		env.add(new Wall(0, 0, 1000, 10));
		env.add(new Wall(0, 0, 10, 300));
		env.add(new Wall(0, 290, 1000, 10));
		env.add(new Wall(990, 0, 10, 100));
		env.add(new Wall(700, 100, 300, 10));
		env.add(new Wall(700, 100, 10, 90));
		env.add(new Wall(990, 200, 10, 100));
		env.add(new Wall(840, 200, 150, 10));
		env.add(new Wall(0, 240, 100, 10));
		env.add(new Wall(100, 90, 10, 160));
		env.add(new Wall(100, 90, 120, 10));
		env.add(new Wall(280, 90, 250, 10));
		env.add(new Wall(350, 90, 10, 70));
		env.add(new Wall(230, 150, 10, 100));
		env.add(new Wall(230, 240, 60, 10));
		env.add(new Wall(350, 240, 10, 60));
		env.add(new Wall(350, 240, 60, 10));
		env.add(new Wall(530, 240, 150, 10));
		env.add(new Wall(680, 240, 10, 60));
		env.add(new Wall(630, 0, 10, 160));
		env.add(new Wall(460, 160, 180, 10));
		env.add(new Wall(460, 160, 10, 70));
		env.add(new Wall(160, 160, 10, 140));
		env.add(new Wall(160, 150, 200, 10));
		env.add(new Beacon(990, 150));
		return env;
	}

	/**
	 * Attempts loading file configuration, falls back to default on fail
	 * 
	 * @param m
	 *            moveable robot
	 * @param file
	 *            configuration file
	 * @return a simulation environment
	 */
	public static SimulationEnvironment tryConfiguration(String file) {
		SimulationEnvironment retu = null;
		final int MAX_NUM_ATTEMPTS = 5;
		int numAttempts = 0;
		while (retu == null && numAttempts++ < MAX_NUM_ATTEMPTS) {
			try {
				retu = loadConfiguration(file);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				retu = null;
				e.printStackTrace();
			}
		}

		if (retu == null) {
			retu = getDefaultConfiguration();
		}

		return retu;
	}

	/**
	 * Attempts loading file configuration
	 * 
	 * @param m
	 *            moveable robot
	 * @param file
	 *            configuration file
	 * @return a simulation environment
	 * @throws IOException
	 *             when file read fails
	 */
	public static SimulationEnvironment loadConfiguration(String localFile)
			throws IOException {
		SimulationEnvironment env = new SimulationEnvironment();
		BufferedReader in = new BufferedReader(new FileReader(localFile));
		String line = "";
		while ((line = in.readLine()) != null) {
			StringTokenizer st = new StringTokenizer(line, ",");
			if (st.countTokens() > 1) {
				String type = st.nextToken();
				if (type.equals("Start")) {
					double xstart = Double.parseDouble(st.nextToken());
					double ystart = Double.parseDouble(st.nextToken());
					if (st.hasMoreTokens()) {
						double orientation = Double.parseDouble(st.nextToken());
						// env.setPosition(xstart, ystart, orientation);
					} else {
						// env.setPosition(xstart, ystart, 0.0);
					}
				}

				if (type.equals("Wall")) {
					double x = Double.parseDouble(st.nextToken());
					double y = Double.parseDouble(st.nextToken());
					double width = 0;
					double height = 0;
					String wString = st.nextToken();
					if (wString.trim().equals("*")) {
						width = WALL_WIDTH;
					} else {
						width = Double.parseDouble(wString);
					}

					String hString = st.nextToken();
					if (hString.trim().equals("*")) {
						height = WALL_WIDTH;
					} else {
						height = Double.parseDouble(hString);
					}

					env.add(new Wall(x, y, width, height));
				}
				if (type.equals("Beacon")) {
					env.add(new Beacon(Double.parseDouble(st.nextToken()),
							Double.parseDouble(st.nextToken())));
				}
			}

		}
		return env;
	}

	public static SimulationEnvironment loadConfiguration(URL url)
			throws IOException {
		// SimulationEnvironment env = new SimulationEnvironment();
		// BufferedReader in = new BufferedReader(new InputStreamReader(
		// (InputStream) url.getContent()));
		//
		// String line = "";
		// while ((line = in.readLine()) != null) {
		// StringTokenizer st = new StringTokenizer(line, ",");
		// if (st.countTokens() > 1) {
		// String type = st.nextToken();
		// if (type.equals("Start")) {
		// double xstart = Double.parseDouble(st.nextToken());
		// double ystart = Double.parseDouble(st.nextToken());
		// if (st.hasMoreTokens()) {
		// double orientation = Double.parseDouble(st.nextToken());
		// env.setPosition(xstart, ystart, orientation);
		// } else
		// env.setPosition(xstart, ystart, 0.0);
		// }
		//
		// if (type.equals("Wall")) {
		// double x = Double.parseDouble(st.nextToken());
		// double y = Double.parseDouble(st.nextToken());
		// double width = 0;
		// double height = 0;
		// String wString = st.nextToken();
		// if (wString.trim().equals("*")) {
		// width = WALL_WIDTH;
		// } else {
		// width = Double.parseDouble(wString);
		// }
		//
		// String hString = st.nextToken();
		// if (hString.trim().equals("*")) {
		// height = WALL_WIDTH;
		// } else {
		// height = Double.parseDouble(hString);
		// }
		//
		// env.add(new Wall(x, y, width, height));
		// }
		// if (type.equals("Beacon")) {
		// env.add(new Beacon(Double.parseDouble(st.nextToken()),
		// Double.parseDouble(st.nextToken())));
		// }
		// }
		//
		// }
		// return env;
		return null;
	}

}